package com.wx.adapter.http.config;

import feign.Logger;
import feign.Request;
import feign.Response;
import feign.Util;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.IOException;

import static feign.Util.UTF_8;
import static feign.Util.decodeOrDefault;

/**
 * wx_back_end
 *
 * @Auther: cheng.tang
 * @Date: 2023/2/10 9:10 PM
 * @Description:
 */
@Slf4j
@Component
public class WxBackEndFeignLogger extends Logger {

    private static final String CLASS_NAME = WxBackEndFeignLogger.class.getSimpleName();

    @Value("${log.threshold.cost.s:3}")
    private long logWarnTagThreshold;

    @Override
    protected void log(String configKey, String format, Object... args) {
        log.info("{} {} {} ", CLASS_NAME, configKey, String.format(format, args));
    }


    @Override
    protected Response logAndRebufferResponse(String configKey, Level logLevel, Response response, long elapsedTime) throws IOException {
        if (response == null) {
            return null;
        }
        String responseContent = "";
        if (response.body() != null) {
            byte[] bodyData = Util.toByteArray(response.body().asInputStream());
            int length = bodyData.length;
            if (length > 0) {
                responseContent = decodeOrDefault(bodyData, UTF_8, "Binary data");
                log(response, elapsedTime, responseContent);
                return response.toBuilder().body(bodyData).build();
            }
        }
        log(response, elapsedTime, responseContent);
        return response;
    }

    private void log(Response response, long elapsedTime, String responseContent) {
        Request feignRequest = response.request();
        String httpMethodName = feignRequest.httpMethod().name();
        String url = feignRequest.url();
        String requestBody = transferRequestBody(feignRequest);
        int status = response.status();
        if (elapsedTime > logWarnTagThreshold * 1000) {
            log.info("{} 慢接口 【 TODOLIST 】 大于3秒 cost:[{}]ms, status {} \n{} {} \nrequest:{} \nresponse:{}", CLASS_NAME, elapsedTime, status, httpMethodName, url, requestBody, responseContent);
        } else {
            log.info("{} cost:[{}]ms, status {} \n{} {} \nrequest:{} \nresponse:{}", CLASS_NAME, elapsedTime, status, httpMethodName, url, requestBody, responseContent);
        }
    }

    private String transferRequestBody(Request request) {
        if (request.body() != null) {
            return request.charset() != null
                    ? new String(request.body(), request.charset())
                    : "";
        }
        return "";
    }

    @Override
    protected void logRetry(String configKey, Level logLevel) {
        log.info("{} {} {} ---> RETRYING", CLASS_NAME, logLevel.name(), configKey);
    }

    @Override
    protected IOException logIOException(String configKey, Level logLevel, IOException ioe, long elapsedTime) {
        log.info("{} {} {} cost {} {} ", CLASS_NAME, logLevel.name(), configKey, elapsedTime, ioe.getMessage());
        return ioe;
    }

    @Override
    protected void logRequest(String configKey, Level logLevel, Request request) {
    }

}
